package available

import (
	"context"
	"errors"
	"google.golang.org/grpc"
	"sync"
	"time"
)

type FixedWindowBuilder struct {
	// 起始位置
	timestamp time.Time
	// 窗口大小
	size time.Duration
	// 最大速率
	rate int32
	// 当前速率
	cur int32

	mu sync.Mutex
}

func (t *FixedWindowBuilder) Close() {}

func (t *FixedWindowBuilder) Build() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
		t.mu.Lock()
		defer func() {
			t.cur--
			t.mu.Unlock()
		}()
		if time.Now().After(t.timestamp.Add(t.size)) {
			// 窗口过期，重置窗口
			t.timestamp = time.Now()
			t.cur = 0

		}
		if t.cur >= t.rate {
			return nil, errors.New("限流：到达上限")
		}

		t.cur++
		return handler(ctx, req)

	}
}

func NewFixedWindowBuilder(size time.Duration, rate int32) *FixedWindowBuilder {
	f := &FixedWindowBuilder{
		size:      size,
		timestamp: time.Now(),
		rate:      rate,
	}

	return f
}
